package com.antexpress.dao;

import com.antexpress.pojo.Employee;
import com.antexpress.pojo.Title;
import java.util.List;
import org.hibernate.Criteria;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.criterion.Expression;
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

/**
 *
 * @author Andy
 */
@Repository
public class EmployeeDAOImpl implements EmployeeDAO{
    @Autowired  
    private SessionFactory sessionFactory;
    
    private Session getSession(){ 
        return sessionFactory.getCurrentSession();
    }  
    
    @Override
    public Employee getEmployeeByUsername(String username) {
        Session session = getSession();
        Criteria crit = session.createCriteria(Employee.class);
        crit.add(Restrictions.eq("username", username));
        
        List<Employee> empList = crit.list();
            
        Employee result = null;
        if(!empList.isEmpty())
            result = empList.get(0);
        return result;
    }

    @Override
    public boolean updateEmployee(Employee emp) {
        Session session = getSession();
        boolean isSuccess = false;
        Transaction trans = null;
        try{
            trans = session.beginTransaction();
            session.update(emp);
            trans.commit();
            session.flush();
            isSuccess = true;
        }catch(Exception e){
            e.printStackTrace();
            if(trans!=null)
                trans.rollback();
            isSuccess = false;
        }
        return isSuccess;
    }

    @Override
    public int getAllRowCount() {
        Session session = getSession();
        Criteria crit = session.createCriteria(Employee.class);
        crit.setProjection(Projections.rowCount());
        Long count = (Long) crit.uniqueResult();
        return count.intValue();
    }

    @Override
    public boolean addEmployee(Employee emp) {
        Session session = getSession();
        boolean isSuccess = false;
        Transaction trans = null;
        try{
            trans = session.beginTransaction();
            session.save(emp);
            trans.commit();
            session.flush();
            isSuccess =true;
        }catch(Exception e){
            e.printStackTrace();
            if(trans!=null)
                trans.rollback();
            isSuccess = false;
        }
        return isSuccess;
    }

    @Override
    public boolean isUsernameExisted(String username) {
        Session session = getSession();
        Criteria crit = session.createCriteria(Employee.class);
        crit.add(Restrictions.eq("username", username));
        
        List<Employee> empList = crit.list();
            
        if(empList.isEmpty())
            return false;
        return true;
    }

    @Override
    public Employee getEmployeeById(String id) {
        Session session = getSession();
        Criteria crit = session.createCriteria(Employee.class);
        crit.add(Restrictions.eq("id", id));
        List<Employee> empList = crit.list();
            
        Employee result = null;
        if(!empList.isEmpty())
            result = empList.get(0);
        return result;
    }

    @Override
    public boolean isEmailExisted(String email) {
        Session session = getSession();
        Criteria crit = session.createCriteria(Employee.class);
        crit.add(Restrictions.eq("email", email));

        List<Employee> empList = crit.list();
            
        if(empList.isEmpty())
            return false;
        return true;
    }

    @Override
    public boolean batchUpdateEmp(List<Employee> emps) {
        Session session = getSession();
        boolean isSuccess = false;
        Transaction trans = null;
        try{
            trans = session.beginTransaction();
            for(Employee emp:emps){
                session.save(emp);
            }
            trans.commit();
            session.flush();
            isSuccess =true;
        }catch(Exception e){
            e.printStackTrace();
            if(trans!=null)
                trans.rollback();
            isSuccess = false;
        }
        return isSuccess;
    }

    @Override
    public List<Employee> listEmpForPage(String name, String mobile, Title title, int offset, int length) {
        Session session = getSession();
        Criteria crit = session.createCriteria(Employee.class);
        crit.setFirstResult(offset);
        crit.setMaxResults(length);
        if(name!=null&&!name.equals(""))
            crit.add(Restrictions.like("name", name, MatchMode.ANYWHERE).ignoreCase());
        if(mobile!=null&&!mobile.equals(""))
            crit.add(Restrictions.like("mobile", mobile, MatchMode.ANYWHERE));
        if(title!=null)
            crit.add(Restrictions.eq("title", title));
        crit.add(Restrictions.not(Expression.eq("status", -10)));
        crit.addOrder(Order.desc("createtime"));
        crit.addOrder(Order.desc("updatetime"));
        List<Employee> empList = crit.list();
        return empList;
    }
    
    @Override
    public List<Employee> listEmpForPageByTitles(String name, String mobile, List<Title> titles, int offset, int length) {
        Session session = getSession();
        Criteria crit = session.createCriteria(Employee.class);
        crit.setFirstResult(offset);
        crit.setMaxResults(length);
        if(name!=null&&!name.equals(""))
            crit.add(Restrictions.like("name", name, MatchMode.ANYWHERE).ignoreCase());
        if(mobile!=null&&!mobile.equals(""))
            crit.add(Restrictions.like("mobile", mobile, MatchMode.ANYWHERE));
        if(!titles.isEmpty())
            crit.add(Restrictions.in("title", titles));
        crit.add(Restrictions.not(Expression.eq("status", -10)));
        crit.addOrder(Order.desc("createtime"));
        crit.addOrder(Order.desc("updatetime"));
        List<Employee> empList = crit.list();
        return empList;
    }

    @Override
    public int getRowCountByTitle(String name, String mobile, Title title) {
        Session session = getSession();
        Criteria crit = session.createCriteria(Employee.class);
        if(name!=null&&!name.equals(""))
            crit.add(Restrictions.like("name", name, MatchMode.ANYWHERE).ignoreCase());
        if(mobile!=null&&!mobile.equals(""))
            crit.add(Restrictions.like("mobile", mobile, MatchMode.ANYWHERE));
        if(title!=null)
            crit.add(Restrictions.eq("title", title));
        crit.add(Restrictions.not(Expression.eq("status", -10)));
        crit.setProjection(Projections.rowCount());
        Long count = (Long) crit.uniqueResult();
        return count.intValue();
    }

    @Override
    public int getRowCountByTitles(String name, String mobile, List<Title> titles) {
        Session session = getSession();
        Criteria crit = session.createCriteria(Employee.class);
        if(name!=null&&!name.equals(""))
            crit.add(Restrictions.like("name", name, MatchMode.ANYWHERE).ignoreCase());
        if(mobile!=null&&!mobile.equals(""))
            crit.add(Restrictions.like("mobile", mobile, MatchMode.ANYWHERE));
        if(!titles.isEmpty())
            crit.add(Restrictions.in("title", titles));
        crit.add(Restrictions.not(Expression.eq("status", -10)));
        crit.setProjection(Projections.rowCount());
        Long count = (Long) crit.uniqueResult();
        return count.intValue();
    }

    @Override
    public List<Employee> getEmpsByTitle(Title title) {
        Session session = getSession();
        Criteria crit = session.createCriteria(Employee.class);
        crit.add(Restrictions.eq("title", title));
        crit.add(Restrictions.not(Expression.eq("status", -10)));
        List<Employee> empList = crit.list();
        return empList;
    }

    @Override
    public List<Employee> getEmpsByTitles(List<Title> titles) {
        Session session = getSession();
        Criteria crit = session.createCriteria(Employee.class);
        crit.add(Restrictions.in("title", titles));
        crit.add(Restrictions.not(Expression.eq("status", -10)));
        List<Employee> empList = crit.list();
        return empList;
    }

    @Override
    public int getInServiceEmpNum() {
        Session session = getSession();
        Criteria crit = session.createCriteria(Employee.class);
        crit.add(Restrictions.eq("status", 0));
        crit.setProjection(Projections.rowCount());
        Long count = (Long) crit.uniqueResult();
        return count.intValue();
    }

    @Override
    public List<Employee> getInServiceEmpsByTitle(Title title) {
        Session session = getSession();
        Criteria crit = session.createCriteria(Employee.class);
        crit.add(Restrictions.eq("title", title));
        crit.add(Restrictions.ge("status", 0));
        List<Employee> empList = crit.list();
        return empList;
    }
    
    @Override
    public int getLeavingEmpNum() {
        Session session = getSession();
        Criteria crit = session.createCriteria(Employee.class);
        crit.add(Restrictions.eq("status", 1));
        crit.setProjection(Projections.rowCount());
        Long count = (Long) crit.uniqueResult();
        return count.intValue();
    }
}
